package org.linphone.sub.audio;

import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.util.Log;

/**
 * Created by Xiang on 2018/4/9.
 */

public class AudioCapturer {

	//log日志打印索引
	private static final String TAG = "AudioCapturer";
	//获取音频数据的来源
	private static final int DEFAULT_SOURCE = MediaRecorder.AudioSource.MIC;
	//音频采样率
	private static final int DEFAULT_SAMPLE_RATE = 48000;
	//音频声道类型，此处设置为双声道
	private static final int DEFAULT_CHANNEL_CONFIG = AudioFormat.CHANNEL_IN_STEREO;
	//音频数据格式有8位和16位，此处设置为16位
	private static final int DEFAULT_DATA_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
	// 音频数据采样样本大小
	private static final int SAMPLES_PER_FRAME = 10240;
	//录音类
	private AudioRecord mAudioRecord;
	//录音线程
	private Thread mCaptureThread;
	//是否开启录音标识
	private boolean mIsCaptureStarted = false;
	//volatile保证内存中数据实时更新
	private volatile boolean mIsLoopExit = false;
	//录音开始监听者
	private OnAudioFrameCapturedListener mAudioFrameCapturedListener;
	//开启录音监听者
	public interface OnAudioFrameCapturedListener {
		void onAudioFrameCaptured(byte[] audioData);
	}
	//判断是否开始录音
	public boolean isCaptureStarted() {
		return mIsCaptureStarted;
	}
	//设置录音监听者
	public void setOnAudioFrameCapturedListener(OnAudioFrameCapturedListener listener) {
		mAudioFrameCapturedListener = listener;
	}
	//准备开启录音类
	public boolean startCapture() {
		return startCapture(DEFAULT_SOURCE, DEFAULT_SAMPLE_RATE, DEFAULT_CHANNEL_CONFIG, DEFAULT_DATA_FORMAT);
	}
	//开启录音类
	public boolean startCapture(int audioSource, int sampleRateInHz, int channelConfig, int audioFormat) {
		//判断录音是否开启
		if (mIsCaptureStarted) {
			Log.e(TAG, "录音已经开启 !");
			return false;
		}
		//获取录音数据最小样本并初级判断数据正确性
		int minBufferSize = AudioRecord.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat);
		Log.i(TAG, "startCapture: "+minBufferSize);
		if (minBufferSize == AudioRecord.ERROR_BAD_VALUE) {
			Log.e(TAG, "错误的音频数据 !");
			return false;
		}
		//开启录音的核心
		mAudioRecord = new AudioRecord(audioSource, sampleRateInHz, channelConfig, audioFormat, minBufferSize * 4);
		if (mAudioRecord.getState() == AudioRecord.STATE_UNINITIALIZED) {
			Log.e(TAG, "AudioRecord 初始化失败 !");
			return false;
		}
		mAudioRecord.startRecording();
		mIsLoopExit = false;
		//开启录音线程并初始化
		mCaptureThread = new Thread(new AudioCaptureRunnable());
		mCaptureThread.start();
		mIsCaptureStarted = true;
		Log.i(TAG, "录音线程开启成功 !");
		return true;
	}

	//停止录音线程
	public void stopCapture() {
		if (!mIsCaptureStarted) {
			return;
		}
		mIsLoopExit = true;
		try {
			mCaptureThread.interrupt();
			mCaptureThread.join(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		if (mAudioRecord.getRecordingState() == AudioRecord.RECORDSTATE_RECORDING) {
			mAudioRecord.stop();
		}
		//清除缓存
		mAudioRecord.release();
		mIsCaptureStarted = false;
		mAudioFrameCapturedListener = null;
		Log.i(TAG, "停止录音线程成功!");
	}

	//录音线程核心
	private class AudioCaptureRunnable implements Runnable {
		@Override
		public void run() {
			while (!mIsLoopExit) {
				byte[] buffer = new byte[SAMPLES_PER_FRAME * 2];
				int ret = mAudioRecord.read(buffer, 0, buffer.length);
				if (ret == AudioRecord.ERROR_INVALID_OPERATION) {
					Log.e(TAG, "Error 运算错误");
				} else if (ret == AudioRecord.ERROR_BAD_VALUE) {
					Log.e(TAG, "Error 生成数据错误");
				} else {
					//成功获取到音频数据
					if (mAudioFrameCapturedListener != null) {
						mAudioFrameCapturedListener.onAudioFrameCaptured(buffer);
					}
				}
			}
		}
	}

}
